#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "include/loop_queue.h"

// TODO 循环队列扩容
static void ensureCap(LoopQueue* q, int newCap) {
    int* newElems = (int*)malloc(sizeof(int) * newCap); 
    assert(newElems != NULL);  // 分配失败及时报错
    for (int i = 0; i < q->size; i++) {
        newElems[i] = q->elems[(q->head + i) % q->cap];
    }
    free(q->elems); // 释放掉原来的内存块
    q->elems = newElems; 
    q->head = 0;
    q->tail = q->size;
    q->cap = newCap; 
}

void LoopQueueNew(LoopQueue* q) {
    q->head = q->tail = q->size = 0;
    q->cap = 4;
    q->elems = (int*)malloc(sizeof(int) * q->cap);
    assert(q->elems != NULL); 
}
void LoopQueueEnqueue(LoopQueue* q, int elem) {
    if (q->size == q->cap) ensureCap(q, q->cap * 2); 

    q->elems[q->tail] = elem;
    q->tail = (q->tail + 1) % q->cap; // 尾索引循环起来
    q->size++;
}
int LoopQueueDequeue(LoopQueue* q) {
    if (q->size == 0) {
        puts("loop queue is empty"); 
        exit(EXIT_FAILURE);    
    }
    int elem = q->elems[q->head];
    q->head = (q->head + 1) % q->cap;
    q->size--;
    // 缩容
    if (q->size == q->cap / 4 && q->cap / 2 != 0) ensureCap(q, q->cap / 2);
    return elem; 
}
int LoopQueueFront(LoopQueue* q) {
    if (q->size == 0) {
        puts("loop queue is empty"); 
        exit(EXIT_FAILURE);    
    }
    return q->elems[q->head]; // 查看队首元素
}
int LoopQueueSize(LoopQueue* q) {
    return q->size; 
}
int LoopQueueIsEmpty(LoopQueue* q) {
    return q->size == 0; 
}
void LoopQueueString(LoopQueue* q) {
    printf("LoopQueue(head = %d, tail = %d, size = %d, cap = %d):\n",
        q->head, q->tail, q->size, q->cap);
    printf(" > head[");
    for (int i = 0; i < q->size; i++) {
        printf("%d", q->elems[(q->head + i) % q->cap]);
        if (i != q->size - 1) 
            printf(", "); 
    }
    printf("]tail\n");
} 
void LoopQueueDispose(LoopQueue* q) {
    if (q->elems) {
        free(q->elems); 
    }
}